package com.gexiaobao.pigeon.app.util

import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.text.TextUtils
import android.view.View
import com.gexiaobao.pigeon.R
import com.gexiaobao.pigeon.app.rxui.tablayout.listener.ImageFileCropEngine
import com.gexiaobao.pigeon.app.rxui.tablayout.listener.MeOnCameraInterceptListener
import com.gexiaobao.pigeon.ui.fragment.mine.pigeon.activity.ActivityUploadPigeonVideo
import com.gexiaobao.pigeon.ui.listener.MeOnVideoThumbnailEventListener
import com.gexiaobao.pigeon.ui.view.CustomLoadingDialog
import com.luck.picture.lib.basic.PictureContentResolver
import com.luck.picture.lib.basic.PictureMediaScannerConnection
import com.luck.picture.lib.config.PictureMimeType
import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.config.SelectorConfig
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnCameraInterceptListener
import com.luck.picture.lib.interfaces.OnCustomLoadingListener
import com.luck.picture.lib.interfaces.OnPermissionDeniedListener
import com.luck.picture.lib.interfaces.OnPermissionDescriptionListener
import com.luck.picture.lib.interfaces.OnPreviewInterceptListener
import com.luck.picture.lib.interfaces.OnVideoThumbnailEventListener
import com.luck.picture.lib.utils.ActivityCompatHelper
import com.luck.picture.lib.utils.BitmapUtils
import com.luck.picture.lib.utils.MediaUtils
import com.luck.picture.lib.utils.PictureFileUtils
import com.luck.picture.lib.utils.SdkVersionUtils
import me.hgj.jetpackmvvm.base.appContext
import me.hgj.jetpackmvvm.util.LogUtils
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.InputStream
import java.io.OutputStream

/**
 * @Author      : hxw
 * @Date        : 2023/7/26 16:02
 * @Describe    :
 */
object PictureUtil {


    fun saveBitmapToGallery(bitmap: Bitmap, context: Context) {
        val filename = "image_${System.currentTimeMillis()}.jpg"

        // 适配 Android Q 及以上版本
        val fos: OutputStream? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val contentValues = ContentValues().apply {
                put(MediaStore.Images.Media.DISPLAY_NAME, filename)
                put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
                put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
            }
            val uri: Uri? = context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
            uri?.let { context.contentResolver.openOutputStream(it) }
        } else {
            // Android Q 之前的版本
            val imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
            val file = File(imagesDir, filename)
            FileOutputStream(file)
        }

        fos?.use {
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it)
            RxToast.showToast(appContext.getString(R.string.save_to_album))
        }
    }


    fun saveBitmapToFile(bitmap: Bitmap, context: Context): Uri? {
        val file = File(context.cacheDir, "image_${System.currentTimeMillis()}.png")
        return try {
            FileOutputStream(file).use { outputStream ->
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
            }
            Uri.fromFile(file) // 返回文件的 URI
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }


    fun getBitmapFromView(view: View): Bitmap {
        // 创建 Bitmap
        val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
        // 创建画布并将视图绘制到上面
        val canvas = Canvas(bitmap)
        view.draw(canvas)
        return bitmap
    }


    fun printImageInfoFromUrl(url: String) {
        val client = OkHttpClient()

        // Start a new thread to handle the network operation
        Thread {
            try {
                // Create a request to fetch the image
                val request = Request.Builder().url(url).build()
                val response: Response = client.newCall(request).execute()

                // Ensure the response is successful
                if (response.isSuccessful) {
                    response.body?.byteStream()?.use { inputStream: InputStream ->
                        // Decode the image dimensions without loading the full image into memory
                        val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
                        BitmapFactory.decodeStream(inputStream, null, options)

                        // Get the image dimensions
                        val width = options.outWidth
                        val height = options.outHeight

                        // Estimate quality based on dimensions (this is just an example, adjust as needed)
                        val quality = estimateImageQuality(width, height)
                        val size = getImageSizeInBytes(inputStream)
                        val imageSizeInKB = size / 1024.0
                        // Print the dimensions and estimated quality
                        LogUtils.warnInfo("Image Dimensions: $width x $height")
                        LogUtils.warnInfo("Estimated Image Quality: $quality<-->size:$imageSizeInKB")
                    } ?: LogUtils.warnInfo("Failed to get the input stream")
                } else {
                    LogUtils.warnInfo("Failed to fetch the image: ${response.message}")
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }.start()
    }

    private fun getImageSizeInBytes(inputStream: InputStream): Long {
        val byteArrayOutputStream = ByteArrayOutputStream()
        val buffer = ByteArray(8192)
        var bytesRead: Int
        var totalBytes: Long = 0

        // Read the input stream and write it to the ByteArrayOutputStream
        while (inputStream.read(buffer).also { bytesRead = it } != -1) {
            byteArrayOutputStream.write(buffer, 0, bytesRead)
            totalBytes += bytesRead
        }

        return totalBytes
    }

    // Function to estimate image quality based on dimensions (customize as needed)
    private fun estimateImageQuality(width: Int, height: Int): String {
        return when {
            width > 4000 && height > 3000 -> "High"
            width > 2000 && height > 1500 -> "Medium"
            else -> "Low"
        }
    }

    /**
     * 裁剪引擎
     *
     * @return
     */
    fun getCropFileEngine(): ImageFileCropEngine {
        return ImageFileCropEngine()
    }

    /**
     * 压缩引擎
     *
     * @return
     */
    fun getCompressFileEngine(): ImageFileCompressEngine {
        return ImageFileCompressEngine()
    }

    /**
     * 自定义相机事件
     *
     * @return
     */
    fun getCustomCameraEvent(): OnCameraInterceptListener {
        return MeOnCameraInterceptListener()
    }

    /**
     * 权限说明
     *
     * @return
     */
    fun getPermissionDescriptionListener(): OnPermissionDescriptionListener {
        return MeOnPermissionDescriptionListener()
    }

    /**
     * 自定义预览
     *
     * @return
     */
    fun getPreviewInterceptListener(): OnPreviewInterceptListener {
        return MeOnPreviewInterceptListener()
    }

    /**
     * 权限拒绝后回调
     *
     * @return
     */
    fun getPermissionDeniedListener(): OnPermissionDeniedListener {
        return MeOnPermissionDeniedListener()
    }

    /**
     * 自定义loading
     *
     * @return
     */
    fun getCustomLoadingListener(): OnCustomLoadingListener {
        return OnCustomLoadingListener { context -> CustomLoadingDialog(context) }
    }

    /**
     * 处理视频缩略图
     */
    fun getVideoThumbnailEventListener(): OnVideoThumbnailEventListener {
        return MeOnVideoThumbnailEventListener(getVideoThumbnailDir())
    }

    /**
     * 创建自定义输出目录
     *
     * @return
     */
    private fun getVideoThumbnailDir(): String {
        val externalFilesDir: File? = appContext.getExternalFilesDir("")
        val customFile = File(externalFilesDir!!.absolutePath, "Thumbnail")
        if (!customFile.exists()) {
            customFile.mkdirs()
        }
        return customFile.absolutePath + File.separator
    }

    /**
     * 尝试匹配查找自定义相机返回的路径
     *
     * @param data
     * @return
     */
    fun getOutputPath(data: Intent?, selectorConfig: SelectorConfig?): String {
        if (data == null) {
            return ""
        }
        var outPutUri = data.getParcelableExtra<Uri>(MediaStore.EXTRA_OUTPUT)
        val cameraPath = selectorConfig!!.cameraPath
        val isCameraFileExists = TextUtils.isEmpty(cameraPath) || PictureMimeType.isContent(cameraPath) || File(cameraPath).exists()
        if ((selectorConfig.chooseMode == SelectMimeType.ofAudio() || !isCameraFileExists) && outPutUri == null) {
            outPutUri = data.data
        }
        if (outPutUri == null) {
            return ""
        }
        return if (PictureMimeType.isContent(outPutUri.toString())) outPutUri.toString() else outPutUri.path.toString()
    }

    /**
     * copy录音文件至指定目录
     */
    fun copyOutputAudioToDir(selectorConfig: SelectorConfig) {
        try {
            if (!TextUtils.isEmpty(selectorConfig.outPutAudioDir)) {
                val inputStream = if (PictureMimeType.isContent(selectorConfig.cameraPath)) PictureContentResolver.openInputStream(
                    appContext, Uri.parse(
                        selectorConfig.cameraPath
                    )
                ) else FileInputStream(selectorConfig.cameraPath)
                var audioFileName = ""
                audioFileName = if (TextUtils.isEmpty(selectorConfig.outPutAudioFileName)) {
                    ""
                } else {
                    if (selectorConfig.isOnlyCamera) selectorConfig.outPutAudioFileName else System.currentTimeMillis()
                        .toString() + "_" + selectorConfig.outPutAudioFileName
                }
                val outputFile = PictureFileUtils.createCameraFile(
                    appContext,
                    selectorConfig.chooseMode, audioFileName, "", selectorConfig.outPutAudioDir
                )
                val outputStream = FileOutputStream(outputFile.absolutePath)
                if (PictureFileUtils.writeFileFromIS(inputStream, outputStream)) {
                    MediaUtils.deleteUri(appContext, selectorConfig.cameraPath)
                    selectorConfig.cameraPath = outputFile.absolutePath
                }
            }
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
        }
    }

    /**
     * buildLocalMedia
     *
     * @param absolutePath
     */
    fun buildLocalMedia(absolutePath: String?, selectorConfig: SelectorConfig): LocalMedia {
        val media: LocalMedia = LocalMedia.generateLocalMedia(appContext, absolutePath)
        media.chooseModel = selectorConfig.chooseMode
        if (SdkVersionUtils.isQ() && !PictureMimeType.isContent(absolutePath)) {
            media.sandboxPath = absolutePath
        } else {
            media.sandboxPath = null
        }
        if (selectorConfig.isCameraRotateImage && PictureMimeType.isHasImage(media.mimeType)) {
            BitmapUtils.rotateImage(appContext, absolutePath)
        }
        return media
    }

    /**
     * 刷新相册
     *
     * @param media 要刷新的对象
     */
    fun onScannerScanFile(media: LocalMedia, activity: ActivityUploadPigeonVideo) {
        if (ActivityCompatHelper.isDestroy(activity)) {
            return
        }
        if (SdkVersionUtils.isQ()) {
            if (PictureMimeType.isHasVideo(media.mimeType) && PictureMimeType.isContent(media.path)) {
                PictureMediaScannerConnection(activity, media.realPath)
            }
        } else {
            val path = if (PictureMimeType.isContent(media.path)) media.realPath else media.path
            PictureMediaScannerConnection(activity, path)
            if (PictureMimeType.isHasImage(media.mimeType)) {
                val dirFile = File(path)
                val lastImageId = MediaUtils.getDCIMLastImageId(appContext, dirFile.parent)
                if (lastImageId != -1) {
                    MediaUtils.removeMedia(appContext, lastImageId)
                }
            }
        }
    }

}